﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Collections;
using RAP.Framework.Libary.Utils;
using System.Threading;

namespace RAP.Framework.Libary.Utils
{
    /// <summary>
    /// JSON服务代理对象
    /// </summary>
    public class HttpJsonClient : WebClient
    {
        public HttpJsonClient ( )
            : base ( )
        {
            this.Timeout = 5000;
            this.UniqueId = 0;
            this.Encoding = Encoding.UTF8;
            this.Headers.Add ( "Content-Type", "text/plain; charset=utf-8" );
            this.Headers.Add ( "X-JSON-RPC", "1.0" );
        }

        /// <summary>
        /// 超时设置，单位毫秒
        /// </summary>
        public int Timeout
        {
            get;
            set;
        }

        /// <summary>
        /// JSON服务地址
        /// </summary>
        public string ServiceUrl
        {
            get
            {
                return this.BaseAddress;
            }
            set
            {
                this.BaseAddress = value;
            }
        }

        protected int UniqueId { get; set; }

        protected override WebRequest GetWebRequest ( Uri address )
        {
            HttpWebRequest request = ( HttpWebRequest )base.GetWebRequest ( address );
            request.Timeout = this.Timeout;
            request.ReadWriteTimeout = this.Timeout;
            return request;
        }

        /// <summary>
        /// 调用指定的JSON服务并返回结果
        /// </summary>
        /// <param name="method"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public object CallService ( string method, params object[ ] param )
        {
            IDictionary uploadData = new Hashtable ( );
            uploadData[ "id" ] = this.UniqueId++;
            uploadData[ "method" ] = method;
            uploadData[ "params" ] = param;
			try
			{
				string dataJSON = ( ( object )uploadData ).ToJSON ( );
				dataJSON = this.UploadString ( this.ServiceUrl, dataJSON );
				if ( string.IsNullOrEmpty ( dataJSON ) )
				{
					return null;
				}
				return this.GetJSONResult ( dataJSON );
			}
			catch
			{
				return null;
			}
        }

        /// <summary>
        /// 异步调用指定的JSON服务，无返回值
        /// </summary>
        /// <param name="method"></param>
        /// <param name="param"></param>
        public void InvokeService
        (
            string method,
            IDictionary param,
            Action<object> onComplete = null,
            Action<IDictionary> onError = null
        )
        {
            IDictionary uploadData = new Hashtable ( );
            uploadData[ "id" ] = this.UniqueId++;
            uploadData[ "method" ] = method;
            uploadData[ "params" ] = param;
            try
            {
                this.UploadDataAsync ( new Uri ( this.BaseAddress ), uploadData.ToJSON ( ).ToByteArray ( ) );
                if ( onComplete != null )
                {
                    this.UploadDataCompleted += new UploadDataCompletedEventHandler ( ( object sender, UploadDataCompletedEventArgs e ) =>
                    {
                        object result = null;
                        string resultStr = e.Result.ToText ( );
                        if ( !String.IsNullOrEmpty ( resultStr ) )
                        {
                            try
                            {
                                result = this.GetJSONResult ( resultStr );
                            }
                            catch
                            {
                                IDictionary error = new Hashtable ( );
                                error[ "error" ] = "返回结果类型错误，无法转换成JSON。";
                                error[ "detail" ] = resultStr;
                            }
                        }
                        onComplete ( result );
                    } );
                }
            }
            catch ( Exception e )
            {
                if ( onError != null )
                {
                    IDictionary err = new Hashtable ( );
                    err[ "error" ] = e;
                    onError ( err );
                }
            }

        }

        protected object GetJSONResult ( string data )
        {
            IDictionary result = null;

            try
            {
                result = data.ToDictionary ( );
            }
            catch
            { }
            if ( result == null )
            {
                return null;
            }
            if ( result[ "result" ] != null )
            {
                return result[ "result" ];
            }
            return null;
        }
    }
}
